package com.zy.cat.service.impl;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

import javax.transaction.Transactional;

import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import com.alibaba.fastjson.JSON;
import com.zy.cat.common.utils.CalculateUtil;
import com.zy.cat.common.utils.DateAPIUtils;
import com.zy.cat.common.utils.DrawProportionUtil;
import com.zy.cat.common.utils.ExtendMethod;
import com.zy.cat.common.utils.TJKUtils;
import com.zy.cat.dao.Dao;
import com.zy.cat.entity.dev.CatDevUserInfo;
import com.zy.cat.entity.game.BoxDrawCountHistory;
import com.zy.cat.entity.game.BoxDrawHistory;
import com.zy.cat.entity.game.CVSDrawCountHistory;
import com.zy.cat.entity.game.CVSDrawHistory;
import com.zy.cat.entity.game.CVSEBottleCountHistory;
import com.zy.cat.entity.game.CardDrawBannerConf;
import com.zy.cat.entity.game.CardDrawCountHistory;
import com.zy.cat.entity.game.CardDrawEntryInfo;
import com.zy.cat.entity.game.CardDrawHistory;
import com.zy.cat.entity.game.CardNewHistory;
import com.zy.cat.entity.game.CardPokerDrawCountHistory;
import com.zy.cat.entity.game.CardPokerDrawHistory;
import com.zy.cat.entity.game.FruitCoinCountHistory;
import com.zy.cat.entity.game.FruitDrawHistory;
import com.zy.cat.entity.game.FruitPrinceInfo;
import com.zy.cat.entity.game.FruitRetryCountHistory;
import com.zy.cat.entity.game.TrunDrawCountHistory;
import com.zy.cat.entity.game.TrunDrawExtraRewardInfo;
import com.zy.cat.entity.game.TrunDrawHistory;
import com.zy.cat.entity.game.repository.BoxDrawCountHistoryRepository;
import com.zy.cat.entity.game.repository.BoxDrawHistoryRepository;
import com.zy.cat.entity.game.repository.CVSDrawCountHistoryRepository;
import com.zy.cat.entity.game.repository.CVSDrawHistoryRepository;
import com.zy.cat.entity.game.repository.CVSEBottleCountHistoryRepository;
import com.zy.cat.entity.game.repository.CardDrawBannerConfRepository;
import com.zy.cat.entity.game.repository.CardDrawCountHistoryRepository;
import com.zy.cat.entity.game.repository.CardDrawHistoryRepository;
import com.zy.cat.entity.game.repository.CardNewHistoryRepository;
import com.zy.cat.entity.game.repository.CardPokerDrawCountHistoryRepository;
import com.zy.cat.entity.game.repository.CardPokerDrawHistoryRepository;
import com.zy.cat.entity.game.repository.CatScrollBarInfoRepository;
import com.zy.cat.entity.game.repository.FruitCoinCountHistoryRepository;
import com.zy.cat.entity.game.repository.FruitDrawHistoryRepository;
import com.zy.cat.entity.game.repository.FruitRetryCountHistoryRepository;
import com.zy.cat.entity.game.repository.TrunDrawCountHistoryRepository;
import com.zy.cat.entity.game.repository.TrunDrawHistoryRepository;
import com.zy.cat.entity.game.resp.BoxInfoResp;
import com.zy.cat.entity.game.resp.CVSDrawHistoryResp;
import com.zy.cat.entity.game.resp.CVSInfoResp;
import com.zy.cat.entity.game.resp.CVSPrizeInfoResp;
import com.zy.cat.entity.game.resp.CardDrawBannerResp;
import com.zy.cat.entity.game.resp.CardDrawCountHistoryResp;
import com.zy.cat.entity.game.resp.CardDrawHistoryResp;
import com.zy.cat.entity.game.resp.CardInfoResp;
import com.zy.cat.entity.game.resp.CardNewHistoryResp;
import com.zy.cat.entity.game.resp.CardPokerDrawHistoryResp;
import com.zy.cat.entity.game.resp.FruitCoinCountHistoryResp;
import com.zy.cat.entity.game.resp.FruitDrawHistoryResp;
import com.zy.cat.entity.game.resp.FruitInfoResp;
import com.zy.cat.entity.game.resp.FruitPrinceInfoResp;
import com.zy.cat.entity.game.resp.FruitRetryCountHistoryResp;
import com.zy.cat.entity.game.resp.Prize;
import com.zy.cat.entity.game.resp.ScrollBarInfoResp;
import com.zy.cat.entity.game.resp.TrunDrawExtraRewardResp;
import com.zy.cat.entity.game.resp.TrunDrawHistoryResp;
import com.zy.cat.entity.game.resp.TrunDrawResp;
import com.zy.cat.entity.game.resp.TurntableDrawCountInfo;
import com.zy.cat.entity.resp.Pages;
import com.zy.cat.entity.resp.ResultPage;
import com.zy.cat.service.AsyncService;
import com.zy.cat.service.CacheService;
import com.zy.cat.service.CatDevService;
import com.zy.cat.service.CatGameService;

import lombok.extern.slf4j.Slf4j;

@Service
@Slf4j
/**
 * 
 * @info 
 * @author Link
 * @date 2019-11-26 15:54
 */
public class CatGameServiceImpl implements CatGameService {
	
	/**
	 * 每日弹窗记录,只缓存一天，index：0.首页200弹窗、1.刮刮卡200弹窗、2.神奇便利店200弹窗、3.天天抽奖活动
	 */
	private final String POPUP_RECORD_DAILY_KEY = "CAT_POPUP_RECORD_DAILY_KEY";

	@Autowired
	CVSEBottleCountHistoryRepository cvsEBottleCountHistoryRepository;

	@Autowired
	CVSDrawCountHistoryRepository cvsDrawCountHistoryRepository;

	@Autowired
	CVSDrawHistoryRepository cvsDrawHistoryRepository;
	
	@Autowired
	TrunDrawCountHistoryRepository trunDrawCountHistoryRepository;
	
	@Autowired
	TrunDrawHistoryRepository trunDrawHistoryRepository;

	@Autowired
	FruitCoinCountHistoryRepository fruitCoinCountHistoryRepository;

	@Autowired
	FruitRetryCountHistoryRepository fruitRetryCountHistoryRepository;
	
	@Autowired
	FruitDrawHistoryRepository fruitDrawHistoryRepository;
	
	@Autowired
	CardDrawHistoryRepository cardDrawHistoryRepository;
	
	@Autowired
	CardDrawCountHistoryRepository cardDrawCountHistoryRepository;
	
	@Autowired
	CardDrawBannerConfRepository cardDrawBannerConfRepository;
	
	@Autowired
	CardPokerDrawCountHistoryRepository cardPokerDrawCountHistoryRepository;
	
	@Autowired
	CardPokerDrawHistoryRepository cardPokerDrawHistoryRepository;
	
	@Autowired
	CardNewHistoryRepository cardNewHistoryRepository;
	
	@Autowired
	BoxDrawCountHistoryRepository boxDrawCountHistoryRepository;
	
	@Autowired
	BoxDrawHistoryRepository boxDrawHistoryRepository;
	
	@Autowired
	CatScrollBarInfoRepository catScrollBarInfoRepository;

	@Autowired
	Dao<CVSDrawCountHistory> ddao;
	
	@Autowired
	Dao<Integer> intDao;

	@Autowired
	Dao<CVSEBottleCountHistory> ebdao;

	@Autowired
	Dao<CVSDrawHistory> cddao;
	
	@Autowired
	Dao<CardInfoResp> codao;
	
	@Autowired
	Dao<CVSDrawHistoryResp> cddaoresp;

	@Autowired
	Dao<CVSInfoResp> cvsinfodao;
	
	@Autowired
	Dao<Prize> prizeDao;
	
	@Autowired
	Dao<TrunDrawCountHistory> trunDrawCountDao;
	
	@Autowired
	Dao<TrunDrawHistory> trunDrawHistoryDao;
	
	@Autowired
	Dao<TrunDrawExtraRewardInfo> trunExtraRewardDao;
	
	@Autowired
	Dao<CardDrawEntryInfo> cardDrawEntryInfoDao;
	
	@Autowired
	Dao<CardDrawBannerResp> cardDrawBannerRespDao;

	@Autowired
	Dao<FruitInfoResp> fhdao;
	
	@Autowired
	Dao<BoxInfoResp> boxInfoRespDao;
	
	@Autowired
	Dao<CVSPrizeInfoResp> cvsPrizeInfoRespDao;
	
	@Autowired
	Dao<TurntableDrawCountInfo> turntableDrawCountInfoDao;

	@Autowired
	CacheService cacheService;
	
	@Autowired
	CatDevService catDevService;

	@Autowired
	AsyncService asyncService;
	
	@Autowired
	@Qualifier("redis9")
	RedisTemplate<String, String> redis9;
	
	@Autowired
	@Qualifier("redis15")
	RedisTemplate<String, Object> redis15;

	@Override
	@Transactional
	public CVSInfoResp getCVSInfo(int rtype, String pid) {
		CVSInfoResp result = null;
		List<CVSDrawHistoryResp> daily_pack = new ArrayList<CVSDrawHistoryResp>();
		//获取每日礼包数量
		CVSDrawHistory DailySuprise = cacheService.getCVSDailySuprise(LocalDate.now().toString(), pid);
		CVSDrawHistory timeInfo = cddao.selectOne(new CVSDrawHistory(pid,10,""), "getTodayTimeInfo");
		String stime, etime;
		//是否为新一轮开始，是否为每天第一次进入
		int isStart=0,isFirst=0;

		boolean isStartNewActivity=false;
		
		/* 最近中奖信息为空 */
		if (timeInfo == null) {
			isStartNewActivity=true;
			stime = LocalDate.now().toString();
			etime = LocalDate.now().plusDays(6).toString();
		} else if(TJKUtils.parse2LocalDate(timeInfo.getEtime()).plusDays(1).isAfter(LocalDate.now())){
			/* 正在活动期间 */
			stime = timeInfo.getStime();
			etime = timeInfo.getEtime();
		}else {
			//开启新一轮集碎片活动
			isStartNewActivity=true;
			stime = LocalDate.now().toString();
			etime = LocalDate.now().plusDays(6).toString();
		}
		
		
		String ltime = TJKUtils.DateTime();
		//新一轮活动开始赠送多张碎片
		if (isStartNewActivity) {
			isStart=1;
			isFirst=1;
			/*
			 * 碎片类型: 0.小米扫地机器人、1.iPhone 11、2.小米平衡车、3.优酷会员卡、4.九阳榨汁机、5.9999现金豆红包
			 * <s>除优酷会员卡(13-16) 、其他碎片(3-8)</s>
			 */
			//0.小米扫地机器人、1.iPhone 11、2.小米平衡车、3.优酷会员卡、4.九阳榨汁机、5.9999现金豆红包
			//控制抽中数量
			String[] numArray= {"2","3","5","6","7","8"};
			double[] proportions= {5,5,10,25,30,15};
			List<CVSDrawHistory> historyList=new ArrayList<>();
			for (int i = 0; i < 6; i++) {
				CVSDrawHistory drawHistory = new CVSDrawHistory(TJKUtils.DateTime("yyyy-MM-dd HH:mm:ss:SSS"), pid, 0,
						ltime, 0);
				drawHistory.setStype(i);
				drawHistory.setDtype(2);
				drawHistory.setStime(stime);
				drawHistory.setEtime(etime);
				drawHistory.setZtype(1);
				if (3==i) {
					drawHistory.setDcount(RandomUtils.nextLong(13, 17));
				}else {
					drawHistory.setDcount(Integer.parseInt(CalculateUtil.ratioExtract(numArray, proportions)));
				}
				
				/* 存储抽奖结果 */
				if (cvsDrawHistoryRepository.saveAndFlush(drawHistory) != null) {
					CVSDrawHistoryResp result_item = new CVSDrawHistoryResp();
					result_item.setDtype(drawHistory.getDtype());
					result_item.setZtype(drawHistory.getZtype());
					result_item.setStype(drawHistory.getStype());
					result_item.setDcount(drawHistory.getDcount());
					daily_pack.add(result_item);

					/* 增加6次抽奖机会 */
					CVSDrawCountHistory draws = new CVSDrawCountHistory(LocalDate.now().toString(), pid, 1, 6,
							ltime);
					cvsDrawCountHistoryRepository.saveAndFlush(draws);
				}
				historyList.add(drawHistory);
				cvsDrawHistoryRepository.saveAndFlush(drawHistory);
			}
			/* 存储抽奖结果 */
//			List<CVSDrawHistory> list = cvsDrawHistoryRepository.saveAll(historyList);

			daily_pack=JSON.parseArray(JSON.toJSONString(historyList), CVSDrawHistoryResp.class);
			/* 增加6次抽奖机会 */
			CVSDrawCountHistory draws = new CVSDrawCountHistory(LocalDate.now().toString(), pid, 1, 6,
					ltime);
			cvsDrawCountHistoryRepository.saveAndFlush(draws);
		}else {
			/* 今日第一次进入神奇便利店，赠送每日礼包+6次抽奖机会 */
			if (DailySuprise == null || DailySuprise.getDcount() < 1) {
				isFirst=1;
				/* 存储抽奖次数 */
				int piecesCount = RandomUtils.nextInt(1, 3);
				log.info("-今日第一次进入神奇便利店-->" + piecesCount + "->次抽奖");
				for (int i = 0; i < piecesCount; i++) {
					/* 存储抽奖结果 */
					CVSDrawHistory drawHistory = randCVS(pid, "2");
					drawHistory.setStime(stime);
					drawHistory.setEtime(etime);
					drawHistory.setDtype(2);

					/* 存储抽奖结果 */
					if (cvsDrawHistoryRepository.saveAndFlush(drawHistory) != null) {
						CVSDrawHistoryResp result_item = new CVSDrawHistoryResp();
						result_item.setDtype(drawHistory.getDtype());
						result_item.setZtype(drawHistory.getZtype());
						result_item.setStype(drawHistory.getStype());
						result_item.setDcount(drawHistory.getDcount());
						daily_pack.add(result_item);

						/* 增加6次抽奖机会 */
						CVSDrawCountHistory draws = new CVSDrawCountHistory(LocalDate.now().toString(), pid, 1, 6,
								ltime);
						cvsDrawCountHistoryRepository.saveAndFlush(draws);
					}
				}
			}
		}
		
		result = cvsinfodao.selectOne(new CVSInfoResp(pid, stime, etime), "getCVSInfo");
		result.setDaily_pack(daily_pack);
		result.setIsFirst(isFirst);
		result.setIsStart(isStart);
		
		//加上本日礼包新奖励的碎片
//		for (CVSDrawHistoryResp cvsDrawHistoryResp : daily_pack) {
//			if(cvsDrawHistoryResp.getStype()==0) {
//				result.setSrobot((int) (result.getSrobot()+cvsDrawHistoryResp.getDcount()));
//			}else if (cvsDrawHistoryResp.getStype()==1) {
//				result.setIphone((int) (result.getIphone()+cvsDrawHistoryResp.getDcount()));
//			}else if (cvsDrawHistoryResp.getStype()==2) {
//				result.setMbike((int) (result.getMbike()+cvsDrawHistoryResp.getDcount()));
//			}else if (cvsDrawHistoryResp.getStype()==3) {
//				result.setYouku((int) (result.getYouku()+cvsDrawHistoryResp.getDcount()));
//			}else if (cvsDrawHistoryResp.getStype()==4) {
//				result.setJiuyang((int) (result.getJiuyang()+cvsDrawHistoryResp.getDcount()));
//			}else if (cvsDrawHistoryResp.getStype()==5) {
//				result.setXbeans((int) (result.getXbeans()+cvsDrawHistoryResp.getDcount()));
//			}
//		}

		CVSDrawCountHistory drawCountsInfo = getTodayDrawsCount(pid);
		CVSEBottleCountHistory bottleCountsInfo = cvsEBottleCountHistoryRepository.findByPidAndCtimeAndNtype(pid,
				LocalDate.now().toString(), 1);

		String nstime = "-", dstime = "-";
		if (bottleCountsInfo != null) {
			if (bottleCountsInfo.getEcount() % 3 == 0) {
				if (TJKUtils.parse2LocalDateTime(bottleCountsInfo.getLtime()).plusHours(4)
						.isAfter(LocalDateTime.now())) {
					nstime = TJKUtils.parse2LocalDateTime(bottleCountsInfo.getLtime()).plusHours(4)
							.format(DateAPIUtils.FORMATTER_YYYYMMDDHHMMSS);
				}
			}
		}
		if (drawCountsInfo != null) {
			if (drawCountsInfo.getDcount() < 1) {
				dstime = TJKUtils.parse2LocalDateTime(drawCountsInfo.getLtime()).plusHours(6)
						.format(DateAPIUtils.FORMATTER_YYYYMMDDHHMMSS);
			}
		}

		Map<String, String> einfo = new HashMap<String, String>();
		List<CVSDrawHistory> ehlist = cddao.list(new CVSDrawHistory(pid, 1), "getCVSDrawEList");
		if (ehlist != null) {
			ehlist.forEach(ew -> {
				einfo.put(ew.getEindex() + "", ew.getFid());
			});
		}
		result.setEinfo(einfo);
		result.setNstime(nstime);
		result.setDstime(dstime);
		
		if (result.getDcount() < 0) {
			result.setDcount(0);
		}
		if (result.getNcount() < 0) {
			result.setNcount(0);
		}
		//判断退出奖励弹窗是否已展示
		result.setIsShow(getPopupStatus(2, pid,0));
		//过滤碎片数量
		result=filterNumber(result);
		return result;
	}
	
	/**
	 * 获取弹窗ID
	 * 
	 * @date 2019-12-10 10:34:55
	 * @param index 0.首页、1.刮刮卡、2.神奇便利店
	 * @param openNum
	 * @param type 操作类型(0.获取，1.更新为已弹框)
	 * @return
	 */
	@SuppressWarnings("unchecked")
	private int getPopupStatus(int index, String pid,int type) {
		// 是否展示
		Object object=redis15.opsForHash().get(POPUP_RECORD_DAILY_KEY, pid);
		List<Integer> showPopupList = null;
		Integer isShow=null;
		if (object instanceof List) {
			showPopupList=(List<Integer>) object;
		}else {
			isShow=(Integer) object;
		}
		if (showPopupList==null || showPopupList.size()<1) {
			showPopupList=new ArrayList<>(3);
			showPopupList.addAll(Arrays.asList(null,null,null));
		}
		isShow=showPopupList.get(index)==null?isShow:showPopupList.get(index);
		Integer temp = isShow;
		if (isShow==null) {
			isShow=0;
		}
		//如果操作类型为更新读取状态
		if (type==1 &&  isShow!=1) {
			isShow=1;
		}
		showPopupList.set(index, isShow);
		// 如果不存在
		if (!redis15.hasKey(POPUP_RECORD_DAILY_KEY)) {
			redis15.opsForHash().put(POPUP_RECORD_DAILY_KEY, pid, showPopupList);
			// 设置过期时间为一天
			Date date = Date.from(LocalDateTime.now().with(LocalTime.MAX).atZone(ZoneId.systemDefault()).toInstant());
			redis15.expireAt(POPUP_RECORD_DAILY_KEY, date);
		} else if (!isShow.equals(temp)) {
			// 数据发生变化是进行更新
			redis15.opsForHash().put(POPUP_RECORD_DAILY_KEY, pid, showPopupList);
		}
		return isShow;
	}

	/**
	 * 过滤检查碎片数量
	 * @date 2019-12-10 10:34:55
	 * @param result
	 */
	private CVSInfoResp filterNumber(CVSInfoResp result) {
		
		CVSInfoResp object = JSON.parseObject(JSON.toJSONString(result), CVSInfoResp.class);
		
		//是否已出现异常数量
		ExtendMethod<Integer, Integer> method=(num)->{
			if (num>=50) {
				num=49;
			}
			return num;
		};
		result.setIphone(method.executeMethod(result.getIphone()));
		result.setMbike(method.executeMethod(result.getMbike()));
		result.setJiuyang(method.executeMethod(result.getJiuyang()));
		result.setYouku(method.executeMethod(result.getYouku()));
		result.setSrobot(method.executeMethod(result.getSrobot()));
		result.setXbeans(method.executeMethod(result.getXbeans()));
		//如果检测到有异常,Redis+日志打印
		if (!object.equals(result)) {
			String msg=TJKUtils.DateTime()+": game cvs error pid:"+result.getPid()+",fragment number error";
			log.error(msg);
			String key="CAT_ERROR_CVS_SHOP";
			redis9.opsForList().leftPush(key, msg);
		}
		return result;
	}

	@Override
	@Transactional
	public List<CVSDrawHistoryResp> getCVSDraw(int rtype, String pid) {
		CVSDrawCountHistory minDrawCount = cvsDrawCountHistoryRepository.findByPidAndCtimeAndDtype(pid,
				LocalDate.now().toString(), -1);

		long drawsCount = 0;
		CVSDrawCountHistory countsInfo = getTodayDrawsCount(pid);
		if (countsInfo != null) {
			drawsCount = countsInfo.getDcount();
		}

		/* 存储抽奖结果 */
		CVSDrawHistory drawHistory = null;

		/* 抽奖结果 */
		List<CVSDrawHistoryResp> result = new ArrayList<CVSDrawHistoryResp>();
		CVSDrawHistoryResp result_item = new CVSDrawHistoryResp();

		if (drawsCount < 1) {
			result_item.setLtime(TJKUtils.parse2LocalDateTime(minDrawCount.getLtime()).plusHours(6)
					.format(DateAPIUtils.FORMATTER_YYYYMMDDHHMMSS));
			result.add(result_item);
			return result;
		}

		CVSDrawHistory timeInfo = cddao.selectOne(new CVSDrawHistory(pid,10,""), "getTodayTimeInfo");
		String stime, etime;

		/* 最近中奖信息为空 */
		if (timeInfo == null) {
			stime = LocalDate.now().toString();
			etime = LocalDate.now().plusDays(6).toString();
		} else {
			/* 结束时间是否超过今天 */
			if (TJKUtils.parse2LocalDate(timeInfo.getEtime()).plusDays(1).isAfter(LocalDate.now())) {
				stime = timeInfo.getStime();
				etime = timeInfo.getEtime();
			} else {
				stime = LocalDate.now().toString();
				etime = LocalDate.now().plusDays(6).toString();
			}
		}

		drawHistory = randCVS(pid, "1,2,3");
		drawHistory.setStime(stime);
		drawHistory.setEtime(etime);

		/* 存储抽奖结果 */
		if (cvsDrawHistoryRepository.saveAndFlush(drawHistory) != null) {
			/* 减少抽奖的次数 */
			if (minDrawCount == null) {
				minDrawCount = new CVSDrawCountHistory(LocalDate.now().toString(), pid, -1, 1, TJKUtils.DateTime());
			} else {
				minDrawCount.setDcount(minDrawCount.getDcount() + 1);
				minDrawCount.setLtime(TJKUtils.DateTime());
			}

			if (cvsDrawCountHistoryRepository.saveAndFlush(minDrawCount) != null) {
				result_item.setFid(drawHistory.getFid());
				result_item.setDtype(drawHistory.getDtype());
				result_item.setDcount(drawHistory.getDcount());
				result_item.setStype(drawHistory.getStype());
				result_item.setZtype(drawHistory.getZtype());
				if (drawsCount - 1 < 1) {
					result_item
							.setLtime(LocalDateTime.now().plusHours(6).format(DateAPIUtils.FORMATTER_YYYYMMDDHHMMSS));
				}
				result.add(result_item);

				/* 计算额外奖励 7,13,20,40 */
				if (minDrawCount.getDcount() == 7 || minDrawCount.getDcount() == 13 || minDrawCount.getDcount() == 20
						|| minDrawCount.getDcount() == 40) {
					
					
					CVSDrawHistory drawHistory_e = new CVSDrawHistory(TJKUtils.DateTime("yyyy-MM-dd HH:mm:ss:SSS"), pid,
							1, TJKUtils.DateTime(), 3);
					
					List<Prize> list = prizeDao.list(new CVSDrawHistory(pid), "getEextraRewardsInfo");
					
					String extract = CalculateUtil.ratioExtract(list);
					
					if (extract!=null && Integer.parseInt(extract)==0) {
						int beans = RandomUtils.nextInt(66, 189);
						drawHistory_e.setDcount(beans);
						drawHistory_e.setZtype(0);
					} else {
						drawHistory_e.setZtype(2);
					}
					drawHistory_e.setStime(stime);
					drawHistory_e.setEtime(etime);
					drawHistory_e.setEindex(minDrawCount.getDcount());

					if (cvsDrawHistoryRepository.saveAndFlush(drawHistory_e) != null) {
						result.add(new CVSDrawHistoryResp(drawHistory_e.getFid(), 0, minDrawCount.getDcount(),
								drawHistory_e.getDtype(), drawHistory_e.getZtype(), drawHistory_e.getDcount(),
								drawHistory_e.getStype(), ""));
					}
				}

			}
		}

		/* 异步存储每日抽奖信息 */
		asyncService.insertCVSGameInfo(rtype, pid);
		return result;
	}

	/**
	 * 
	 * @info 抽奖概率计算
	 * @author Link
	 * @date 2019-11-16 11:06
	 * @param pid
	 * @param rands 可抽中的奖项，默认："1,2,3"
	 *              <p>
	 *              （1）现金豆的概率为17% 每次10~66
	 *              </p>
	 *              <p>
	 *              （2）碎片的概率为56%
	 *              </p>
	 *              <p>
	 *              （3）大礼包的概率为27%
	 *              </p>
	 * @return
	 */
	private CVSDrawHistory randCVS(String pid, String rands) {
		/* 存储抽奖结果 */
		CVSDrawHistory drawHistory = new CVSDrawHistory(TJKUtils.DateTime("yyyy-MM-dd HH:mm:ss:SSS"), pid, 1,
				TJKUtils.DateTime(), 0);

		/* 可抽中的奖项 */
		if (StringUtils.isBlank(rands) || (!rands.contains("1") && !rands.contains("2") && !rands.contains("3"))) {
			rands = "1,2,3";
		}
		/* 产生随机数 */
		int rand = RandomUtils.nextInt(1, 101);

		log.info("-中奖类型-->" + rand);
		if (rand <= 17) {
			if (!rands.contains("1")) {
				return randCVS(pid, rands);
			}
			int beans = RandomUtils.nextInt(10, 67);
			drawHistory.setZtype(0);
			drawHistory.setStype(-1);
			drawHistory.setDcount(beans);
		} else if (rand <= 44) {
			if (!rands.contains("3")) {
				return randCVS(pid, rands);
			}
			drawHistory.setZtype(2);
			drawHistory.setDcount(0);
		} else {
			if (!rands.contains("2")) {
				return randCVS(pid, rands);
			}
			/* 商品碎片类型（0.小米扫地机器人、1.iPhone 11、2.小米平衡车、3.优酷会员卡、4.九阳榨汁机、5.9999现金豆红包） */
			int pieces = RandomUtils.nextInt(0, 6);
			log.info("-中奖类型-->" + rand + "--商品碎片->" + pieces);

			List<CVSDrawHistory> draw = cddao.list(new CVSDrawHistory(pid), "getShopPieces");
			if (draw == null || draw.isEmpty()) {
				drawHistory.setZtype(1);
				drawHistory.setStype(pieces);
				drawHistory.setDcount(1);
			} else {
				String drawStr = "";
				for (CVSDrawHistory cvsDrawHistory : draw) {
					/* 碎片大于47（94%），以后不会再被抽中 */
					if (cvsDrawHistory.getDcount() > 47) {
						drawStr += cvsDrawHistory.getStype() + ",";
					}
				}
//				log.info("-中奖类型-->" + rand + "--商品碎片->" + pieces + "--drawStr->" + drawStr);
				int count = 20;
				while (drawStr.contains(pieces + "") && count > 0) {
					pieces = RandomUtils.nextInt(0, 6);
					count--;
				}
//				log.info("-中奖类型-->" + rand + "--商品碎片->" + pieces + "--drawStr->" + drawStr);
				if (!drawStr.contains(pieces + "")) {
					drawHistory.setZtype(1);
					drawHistory.setStype(pieces);
					drawHistory.setDcount(1);
					log.info("-中奖类型-商品碎片->" + pieces);
				} else {
					log.error("-抽奖碎片超出预算，按照随即金币结算-->");
					int beans = RandomUtils.nextInt(10, 67);
					drawHistory.setZtype(0);
					drawHistory.setStype(-1);
					drawHistory.setDcount(beans);
				}
			}
		}
		return drawHistory;
	}

	@Override
	@Transactional
	public Map<String, Object> getCVSEbottle(int rtype, String pid) {
		Map<String, Object> result = new HashMap<String, Object>();
		CVSEBottleCountHistory bottles = cvsEBottleCountHistoryRepository.findByPidAndCtimeAndNtype(pid,
				LocalDate.now().toString(), 1);
		/* 判定是否是今日第一次兑换 */
		if (bottles != null) {
			/* 地N次兑换，如果是3的倍数 */
			if (bottles.getEcount() % 3 == 0) {
				/* 如果在下次截至获取时间之后，可继续获取奖励 */
				if (TJKUtils.secondsInterval(TJKUtils.parse2LocalDateTime(bottles.getLtime()).plusHours(4)
						.format(DateAPIUtils.FORMATTER_YYYYMMDDHHMMSS), TJKUtils.DateTime()) > 0) {
					bottles.setEcount(bottles.getEcount() + 1);
					bottles.setLtime(TJKUtils.DateTime());
				} else {
					/* 不在获取时间，提示并添加最后时间 */
					result.put("code", 0);
					result.put("msg", "没到下次获取时间！请稍后重试");
					result.put("ltime", TJKUtils.parse2LocalDateTime(bottles.getLtime()).plusHours(4)
							.format(DateAPIUtils.FORMATTER_YYYYMMDDHHMMSS));
					return result;
				}
			} else {
				/* 非3的倍数，可继续兑换能量瓶 */
				bottles.setEcount(bottles.getEcount() + 1);
				bottles.setLtime(TJKUtils.DateTime());
			}
		} else {
			bottles = new CVSEBottleCountHistory(LocalDate.now().toString(), pid, 1, 1, TJKUtils.DateTime());
		}
		/* 更新能量瓶信息 */
		if (cvsEBottleCountHistoryRepository.saveAndFlush(bottles) != null) {
			result.put("code", 1);
			result.put("msg", "获取成功");
			if (bottles.getEcount() % 3 == 0) {
				result.put("ltime", LocalDateTime.now().plusHours(4).format(DateAPIUtils.FORMATTER_YYYYMMDDHHMMSS));
			} else {
				result.put("ltime", "");
			}
		}
		/* 异步存储每日抽奖信息 */
		asyncService.insertCVSGameInfo(rtype, pid);
		return result;
	}

	@Override
	public CVSDrawHistoryResp getCVSEPkgs(Integer rtype, CVSDrawHistory history) {
		history.setEstatus(1);
		history.setLtime(TJKUtils.DateTime());
		CVSDrawHistoryResp result = null;
		CVSDrawHistory resulthistory = cvsDrawHistoryRepository.saveAndFlush(history);
		if (resulthistory != null) {
			result = new CVSDrawHistoryResp(history.getFid(), history.getFtype(), history.getEindex(),
					history.getDtype(), history.getZtype(), history.getDcount(), history.getStype(), "-");
		}
		return result;
	}

	@Override
	public CVSEBottleCountHistory getTodayEbottlesCount(String pid) {
		return ebdao.selectOne(new CVSEBottleCountHistory(pid), "getLastBottles");
	}

	@Override
	public CVSDrawCountHistory getTodayDrawsCount(String pid) {
		return ddao.selectOne(new CVSDrawCountHistory(pid), "getLastDraws");
	}

	@Override
	@Transactional
	public boolean getEbottle2Draws(int rtype, String pid) {
		long counts = 0;
		CVSEBottleCountHistory countsInfo = getTodayEbottlesCount(pid);
		if (countsInfo != null) {
			counts = countsInfo.getEcount();
		}

		if (counts < 1) {
			return false;
		}
		CVSEBottleCountHistory bottles = cvsEBottleCountHistoryRepository.findByPidAndCtimeAndNtype(pid,
				LocalDate.now().toString(), -1);
		if (bottles == null) {
			bottles = new CVSEBottleCountHistory(LocalDate.now().toString(), pid, -1, 1, TJKUtils.DateTime());
		} else {
			bottles.setEcount(bottles.getEcount() + 1);
			bottles.setLtime(TJKUtils.DateTime());
		}
		if (cvsEBottleCountHistoryRepository.saveAndFlush(bottles) != null) {
			CVSDrawCountHistory minDrawCount = cvsDrawCountHistoryRepository.findByPidAndCtimeAndDtype(pid,
					LocalDate.now().toString(), 1);
			if (minDrawCount == null) {
				minDrawCount = new CVSDrawCountHistory(LocalDate.now().toString(), pid, 1, 6, TJKUtils.DateTime());
			} else {
				minDrawCount.setDcount(minDrawCount.getDcount() + 6);
				minDrawCount.setLtime(TJKUtils.DateTime());
			}
			if (cvsDrawCountHistoryRepository.saveAndFlush(minDrawCount) != null) {
				/* 异步存储每日抽奖信息 */
				asyncService.insertCVSGameInfo(rtype, pid);
				return true;
			}
		}

		return false;
	}

	@Override
	public ResultPage<CVSDrawHistoryResp> getCVSDrawList(int rtype, String pid, Pages pages) {
		return cddaoresp.listAndPages(new CVSDrawHistory(pid), "getCVSDrawList", pages);
	}

	@Override
	@Transactional
	public CVSDrawHistoryResp getCVSDrawDouble(CVSDrawHistory draw) {
		CVSDrawHistoryResp result = null;
		draw.setFtype(1);
		draw.setDcount(draw.getDcount() * 2);

		CVSDrawHistory resultEntity = cvsDrawHistoryRepository.saveAndFlush(draw);
		if (resultEntity != null) {
			result = new CVSDrawHistoryResp(resultEntity.getFid(), draw.getFtype(), 0, resultEntity.getDtype(),
					resultEntity.getZtype(), resultEntity.getDcount(), resultEntity.getStype(), "-");
		}
		/* 异步存储每日抽奖信息 */
		asyncService.insertCVSGameInfo(0, draw.getPid());
		return result;
	}

	@Override
	public TrunDrawResp getTurnInfo(int rtype, String pid) {
		//响应对象
		TrunDrawResp trunDrawResp=new TrunDrawResp();
		
		//查询今日剩余大转盘抽奖次数
		TrunDrawCountHistory drawCountHistory = trunDrawCountDao.selectOne(new TrunDrawCountHistory(pid), "getTodayDrawsNum");
		int dcount=0;
		if (drawCountHistory==null) {
			//今日第一次抽奖，奖励100次
			drawCountHistory=new TrunDrawCountHistory(LocalDate.now().toString(),pid,
					1,100,TJKUtils.DateTime());
			//保存今日抽奖次数
			trunDrawCountHistoryRepository.saveAndFlush(drawCountHistory);
			dcount=drawCountHistory.getDcount();
		}else {
			dcount=drawCountHistory.getDcount();
		}
		
		List<TrunDrawExtraRewardResp> respList = getTurnExtraRewardList(pid, 100-dcount);
		//返回剩余抽奖次数
		trunDrawResp.setDcount(dcount);		
		trunDrawResp.setExtraRewardList(respList);
		return trunDrawResp;
	}
	
	/**
	 * 获取大转盘额外奖励集合
	 * @param pid
	 * @param dcount
	 * @return
	 */
	private List<TrunDrawExtraRewardResp> getTurnExtraRewardList(String pid, int dcount) {
		//额外奖励查询
		List<TrunDrawHistory> list = trunDrawHistoryDao.list(new TrunDrawHistory(pid), "getTodayExtraRewardHistory");
		//创建额外奖励响应对象
		List<TrunDrawExtraRewardResp> respList = new ArrayList<>();
		int[] extraBeanNumArray= {80,300,500,800};
		int[] extraCountArray= {5,30,60,100};
		//领取状态，-1.未达到领取次数、0.未领取、1.已领取
		int status=-1;
		//之前满足条件数量
		int meetCount=list==null || list.size()<1?0:list.size();
		//最新满足条件数量
		int lastMeetCount=0;
		if (list==null || list.size()<1) {
			for (int i = 0; i < extraCountArray.length; i++) {
				//判断抽奖次数，是否满足额外奖励的次数
				status=dcount>=extraCountArray[i]?0:-1;
				if (status==0) {
					//满足条件+1
					lastMeetCount++;
				}
				respList.add(new TrunDrawExtraRewardResp(extraCountArray[i]+"", status, extraBeanNumArray[i]));
			}
		}else {
			for (int i = 0; i < extraCountArray.length; i++) {
				//判断抽奖次数，是否满足额外奖励的次数
				status=dcount>=extraCountArray[i]?0:-1;
				//判断该额外奖励是否已领取
				if (status==0 && list.size()>=i+1 && list.get(i).getDstatus()==1) {
					status=1;
				}
				if (status!=-1) {
					//满足条件+1
					lastMeetCount++;
				}
				respList.add(new TrunDrawExtraRewardResp(extraCountArray[i]+"", status, extraBeanNumArray[i]));
			}
		}
		//如果最新的满足条件数量，小于之前查询的数量则插入新满足条件的额外奖励
		if (meetCount<lastMeetCount) {
			List<TrunDrawHistory> extraRewardList=new ArrayList<>();
			int btype=2;
			//保存满足条件的数量
			for (int i = meetCount; i < lastMeetCount; i++) {
				//只有首个额外奖励不需要看视频，其他均需要看视频领取
				btype=meetCount==0?1:2;
				extraRewardList.add(new TrunDrawHistory(TJKUtils.DateTime(), -1, pid, 0, 
						btype, 1, extraBeanNumArray[i], 0, TJKUtils.DateTime()));
			}
			trunDrawHistoryRepository.saveAll(extraRewardList);
			trunDrawHistoryRepository.flush();
		}
		return respList;
	}

	@Override
	public TrunDrawResp getTurnDraw(int rtype, String pid) {
		//返回结果
		TrunDrawResp trunDrawResp=new TrunDrawResp();
		
		//获取已消耗的抽奖次数
		TrunDrawCountHistory trunDrawCountHistory=trunDrawCountHistoryRepository.findByPidAndCtimeAndDtype(pid,
				DateAPIUtils.getNowTimeString(DateAPIUtils.FORMATTER_YYYYMMDD), -1);
		
		/* 存储抽奖结果 */
		TrunDrawHistory drawHistory = null;

		/* 抽奖结果 */
		TrunDrawHistoryResp result_item = new TrunDrawHistoryResp();
		//进行抽奖操作
		drawHistory = randTrun(pid, trunDrawCountHistory==null?0:trunDrawCountHistory.getDcount());
		//保存抽奖结果
		trunDrawHistoryRepository.saveAndFlush(drawHistory);
		
		//抽奖次数减少一次
		if (trunDrawCountHistory == null) {
			trunDrawCountHistory = new TrunDrawCountHistory(DateAPIUtils.getNowTimeString(DateAPIUtils.FORMATTER_YYYYMMDD), pid, -1, 1, TJKUtils.DateTime());
		} else {
			trunDrawCountHistory.setDcount(trunDrawCountHistory.getDcount() + 1);
			trunDrawCountHistory.setLtime(TJKUtils.DateTime());
		}
		//保存消耗对象
		trunDrawCountHistoryRepository.saveAndFlush(trunDrawCountHistory);
		
		//异步更新抽奖结果
		asyncService.insertTrunDrawInfo(rtype,pid);
		
		//将中奖对象封装到响应类中
		BeanUtils.copyProperties(drawHistory, result_item);
		//设置剩余抽奖次数
		int tcount = 100-trunDrawCountHistory.getDcount();
		result_item.setTcount(tcount);
		trunDrawResp.setDcount(tcount);
		//设置中奖信息
		trunDrawResp.setLuckyDrawResult(result_item);
		
		//转化为响应类
		List<TrunDrawExtraRewardResp> respList = getTurnExtraRewardList(pid, trunDrawCountHistory.getDcount());
		trunDrawResp.setExtraRewardList(respList);
		
		return trunDrawResp;
	}
	
	
	/**
	 * 大转盘的抽奖计算
	 * @param pid 用户ID
	 * @param consumeCount 已消耗次数 
	 * @description 礼包48%、现金豆52%
	 * @return
	 */
	private TrunDrawHistory randTrun(String pid,int consumeCount) {
		/* 存储抽奖结果 */
		TrunDrawHistory drawHistory = null;
		//获取上次中奖纪录
		TrunDrawHistory lastRecord = trunDrawHistoryDao.selectOne(new TrunDrawHistory(pid), "getTodayLastRecordInfo");
		
		//查询用户等级,0.新用户、1.老用户
		CatDevUserInfo devUserInfo = catDevService.getCatDevUserInfoByPid(pid);
		
		//获取大转盘
		Map<String, Object> turnInstance = DrawProportionUtil.getTurnInstance(devUserInfo.getUtype());
		
		List<Prize> prizeList=JSON.parseArray((String) turnInstance.get("prizeList"), Prize.class);
		List<Prize> advertTypeList=JSON.parseArray((String) turnInstance.get("advertTypeList"), Prize.class);
		List<Prize> btnTypeList=JSON.parseArray((String) turnInstance.get("btnTypeList"), Prize.class);
		
		//获取大转盘的抽奖结果统计
		TurntableDrawCountInfo countInfo = turntableDrawCountInfoDao.selectOne(new TurntableDrawCountInfo(pid), "getTodayResultCount");
		
		//减去已抽中的奖品数
		if (countInfo!=null) {
			getTurntablePrizesNumber(prizeList,advertTypeList,btnTypeList,countInfo);
		}
		
		//抽取中奖类型, 0.现金豆、1礼包(广告)
		String prizeType = CalculateUtil.ratioExtract(prizeList);
		//1. 抽中现金豆
		if ("0".equals(prizeType)) {
			//调用计算抽中现金豆是的方法
			drawHistory=getBeanHis(pid,consumeCount, lastRecord,turnInstance,btnTypeList);
		}else if ("1".equals(prizeType)) {
			//抽中礼包
			//按比重抽取广告类型
			String  advertType= CalculateUtil.ratioExtract(advertTypeList);
			drawHistory=new TrunDrawHistory(TJKUtils.DateTime(), pid, Integer.parseInt(advertType),0, TJKUtils.DateTime());
		}
		
		return drawHistory;
	}

	/**
	 * 计算大转盘奖品剩余数量
	 * @author lipengchao
	 * @date 2020-04-14 11:21:20 
	 * @param prizeList
	 * @param advertTypeList
	 * @param btnTypeList
	 * @param countInfo
	 */
	private void getTurntablePrizesNumber(List<Prize> prizeList, List<Prize> advertTypeList, List<Prize> btnTypeList,
			TurntableDrawCountInfo countInfo) {
		//奖品类型 0.现金豆、 1礼包(广告)
		prizeList.get(0).setPrizeCount(prizeList.get(0).getPrizeCount()-countInfo.getBeanCount());
		prizeList.get(1).setPrizeCount(prizeList.get(1).getPrizeCount()-countInfo.getAdCount());
		
		//广告类型 : 101.展示广告红包,102.互动广告红包
		advertTypeList.get(0).setPrizeCount(advertTypeList.get(0).getPrizeCount()-countInfo.getShowAdCount());
		advertTypeList.get(1).setPrizeCount(advertTypeList.get(1).getPrizeCount()-countInfo.getInteractAdCount());
		
		//按钮类型： 0.领取礼包、1.继续游戏
		btnTypeList.get(0).setPrizeCount(btnTypeList.get(0).getPrizeCount()-countInfo.getBtnAdCount());
		btnTypeList.get(1).setPrizeCount(btnTypeList.get(1).getPrizeCount()-countInfo.getBtnNextCount());
	}

	/**
	 *  大转盘抽奖抽中现金豆时的计算
	 * @param pid 用户id 
	 * @param consumeCount 今日抽奖次数
	 * @param lastRecord 上次抽中的中奖纪录对象
	 * @param turnInstance 抽奖比例对象
	 * @return
	 */
	private TrunDrawHistory getBeanHis(String pid,int consumeCount, TrunDrawHistory lastRecord,Map<String, Object> turnInstance
			,List<Prize> btnPrizeList) {
		
		//获取金豆数量比重
		String[] beanArray= (String[]) turnInstance.get("beanArray");
		double[] beanProportions= (double[]) turnInstance.get("beanProportions");
		//1.1. 获取本次得到现金豆的数量
		int beanNum = CalculateUtil.ratioExtractDouble(beanArray, beanProportions);
		//1.2. 按钮类型
		String btnType;
		
		/**
		 * 1.3  判断已消耗抽奖次数是否大于10次,如果小于按钮直接为继续游戏按钮
		 * 	如果大于10次,测判断是否为11次或者上次抽中的奖品类型不是现金豆(如果为现金豆则是遇到连续两次抽中现金豆的情况需要按钮类型遍历)
		 */
		if (consumeCount<10) {
			btnType="1";
		}else if(consumeCount==11 || (lastRecord!=null && lastRecord.getZtype()!=0)){
			//如果为11次或者上次中奖不是为现金豆, 则按两个按钮正常的占比来抽取
			btnType = CalculateUtil.ratioExtract(btnPrizeList);
		}else {
			//上次中奖记录是现金豆,判断上次中奖的按钮类型是什么，本次要与上次的按钮类型不同
			if (lastRecord.getBtype()==0) {
				//上次为领取礼包，本次测应为继续游戏
				btnType = "1";
			}else {
				//上次为继续游戏，则本次则应是领取礼包
				btnType="0";
			}
		}
		
		return new TrunDrawHistory(TJKUtils.DateTime(), pid, 0, Integer.parseInt(btnType),0, beanNum, TJKUtils.DateTime());
	}
	
	@Override
	public TrunDrawHistoryResp getTurnDrawDouble(int rtype,TrunDrawHistory draw) {
		//设置为已翻倍
		draw.setFtype(1);
		draw.setLtime(TJKUtils.DateTime());
		draw.setDcount(draw.getDcount()*3);
		if(trunDrawHistoryDao.update(draw)==false) {
			log.error("getTurnDrawDouble:pid="+draw.getPid()+"翻倍失败");
			return null;
		}
		//异步更新抽奖结果
		asyncService.insertTrunDrawInfo(rtype,draw.getPid());
		
		TrunDrawHistoryResp resp=new TrunDrawHistoryResp();
		BeanUtils.copyProperties(draw, resp);
		//查询今日剩余大转盘抽奖次数
		TrunDrawCountHistory drawCountHistory = trunDrawCountDao.selectOne(new TrunDrawCountHistory(draw.getPid()), "getTodayDrawsNum");
		resp.setTcount(drawCountHistory.getDcount());
		return resp;
	}

	@Override
	public TrunDrawExtraRewardResp getTurnDrawExtraReward(int rtype,TrunDrawHistory rewardInfo,String code) {
		//状态改为已领取
		rewardInfo.setDstatus(1);
		rewardInfo.setLtime(TJKUtils.DateTime());
		if(trunDrawHistoryRepository.saveAndFlush(rewardInfo)==null) {
			return null;
		}
		//异步更新抽奖结果
		asyncService.insertTrunDrawInfo(rtype,rewardInfo.getPid());
		TrunDrawExtraRewardResp resp=new TrunDrawExtraRewardResp();
		resp.setBeanNum((int)rewardInfo.getDcount());
		resp.setRstatus(1);
		resp.setCode(code);
		return resp;
	}

	@Override
	@Transactional
	public FruitInfoResp getFruitInfo(int rtype, String pid) {
		FruitInfoResp result = null;
		List<FruitPrinceInfoResp> plist = new ArrayList<FruitPrinceInfoResp>();
		/* 判断是否是第一次进入，第一次赠送今日带金币5次，1次兑换代币机会，5次看视频获得代币机会 */
		if (fruitCoinCountHistoryRepository.findByPidAndCtimeAndDtype(pid, LocalDate.now().toString(), 0) == null) {
//			fruitCoinCountHistoryRepository.saveAndFlush(
//					new FruitCoinCountHistory(LocalDate.now().toString(), pid, 0, 5, 0, TJKUtils.DateTime()));
			fruitRetryCountHistoryRepository.saveAndFlush(
					new FruitRetryCountHistory(LocalDate.now().toString(), pid, 1, 5, TJKUtils.DateTime()));
		}
		result = fhdao.selectOne(new FruitInfoResp(pid), "getFruitInfo");
		if (result == null) {
			try {
				Thread.sleep(300);
			} catch (InterruptedException e) {
			}
			result = fhdao.selectOne(new FruitInfoResp(pid), "getFruitInfo");
		}
		if (result == null) {
			return result;
		} else {
			if (result.getDcount() < 0) {
				result.setDcount(0);
			}
			if (result.getRetry() < 0) {
				result.setRetry(0);
			}
			if (result.getVideo() < 0) {
				result.setVideo(0);
			}
		}
		plist = cacheService.getFruitPrinceInfo();
		result.setPlist(plist);
		return result;
	}
	
	@Override
	@Transactional
	public FruitDrawHistoryResp getFruitDeaw(int rtype, String pid, String fpid, int gtype, int gstatus,
			FruitPrinceInfo fruitPrince) {
		FruitDrawHistoryResp result = null;
		int dcount = 0;
		if (fruitPrince.getTtype() == 0) {
			dcount = fruitPrince.getDcoin();
		}

		FruitDrawHistory fruitDrawHistory = new FruitDrawHistory(TJKUtils.DateTime("yyyy-MM-dd HH:mm:ss:SSS" ), fpid, pid, gtype,
				gstatus == 1 ? 30 : 0, gstatus, 1, TJKUtils.DateTime(), "-");

		if (fruitDrawHistoryRepository.saveAndFlush(fruitDrawHistory) != null) {
			if (fruitPrince.getTtype() == 0) {
				FruitCoinCountHistory fruitCoinCountHistory = fruitCoinCountHistoryRepository
						.findByPidAndCtimeAndDtype(pid, LocalDate.now().toString(), -1);
				if (fruitCoinCountHistory == null) {
					fruitCoinCountHistory = new FruitCoinCountHistory(LocalDate.now().toString(), pid, -1, dcount, 0,
							TJKUtils.DateTime());
				} else {
					fruitCoinCountHistory.setDcount(fruitCoinCountHistory.getDcount() + dcount);
					fruitCoinCountHistory.setLtime(TJKUtils.DateTime());
				}
				if (fruitCoinCountHistoryRepository.saveAndFlush(fruitCoinCountHistory) != null) {
				}
			}
			result = new FruitDrawHistoryResp();
			FruitInfoResp info = fhdao.selectOne(new FruitInfoResp(pid), "getFruitInfo");
			if (info != null) {
				if(info.getDcount()<0) {
					TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
					return null;
				}
				result.setDcount(info.getDcount());
				result.setRetry(info.getRetry());
				result.setGcount(gstatus == 1 ? 30 : 0);
			}
		}
		return result;
	}

	@Override
	public FruitCoinCountHistoryResp getFruitDcoin(int rtype, int dtype, String pid) {
		FruitCoinCountHistoryResp result = new FruitCoinCountHistoryResp(-1, -1);
		FruitCoinCountHistory fruit = null;
		if (dtype == 0) {
			List<FruitCoinCountHistory> fruits = fruitCoinCountHistoryRepository
					.findByPidAndCtimeAndDtypeGreaterThanEqualOrderByDtype(pid, LocalDate.now().toString(), 201);
			int coin = RandomUtils.nextInt(3, 6);
			if (fruits == null || fruits.isEmpty()) {
				fruit = new FruitCoinCountHistory(LocalDate.now().toString(), pid, 201, coin, 0, TJKUtils.DateTime());
			} else {
				int dindex = fruits.get(fruits.size() - 1).getDtype() + 1;
				if (dindex <= 205) {
					fruit = new FruitCoinCountHistory(LocalDate.now().toString(), pid, dindex, coin, 0,
							TJKUtils.DateTime());
				} else {
					return result;
				}
			}
		} else if (dtype == 1) {
			fruit = fruitCoinCountHistoryRepository.findByPidAndCtimeAndDtype(pid, LocalDate.now().toString(), dtype);
			if (fruit == null) {
				fruit = new FruitCoinCountHistory(LocalDate.now().toString(), pid, dtype, 5, 0, TJKUtils.DateTime());
			} else {
				return result;
			}
		}else if (dtype == 2) {
			fruit = fruitCoinCountHistoryRepository.findByPidAndCtimeAndDtype(pid, LocalDate.now().toString(), 0);
			if (fruit == null) {
				fruit = new FruitCoinCountHistory(LocalDate.now().toString(), pid, 0, 5, 0 , TJKUtils.DateTime());
			} else {
				return result;
			}
		}
		if (fruit != null) {
			FruitCoinCountHistory resultE = fruitCoinCountHistoryRepository.saveAndFlush(fruit);
			if (resultE != null) {
				result = new FruitCoinCountHistoryResp(resultE.getDtype(), resultE.getDcount());
				return result;
			}
		}
		return result;
	}

	@Override
	public FruitCoinCountHistoryResp getFruitDcoinDouble(int rtype, int dtype, String pid) {
		FruitCoinCountHistoryResp result = null;
		FruitCoinCountHistory fruit = fruitCoinCountHistoryRepository.findByPidAndCtimeAndDtype(pid,
				LocalDate.now().toString(), dtype);

		if (fruit != null && fruit.getFtype() == 0) {
			fruit.setFtype(1);
			fruit.setDcount(fruit.getDcount() * 2);
			fruit.setLtime(TJKUtils.DateTime());
			FruitCoinCountHistory resultEntity = fruitCoinCountHistoryRepository.saveAndFlush(fruit);
			if (resultEntity != null) {
				result = new FruitCoinCountHistoryResp(dtype, resultEntity.getDcount(), resultEntity.getFtype());
			}
		}
		return result;
	}

	@Override
	public FruitRetryCountHistoryResp getFruitRetry(int rtype, String pid) {
		FruitRetryCountHistory retry_1 = fruitRetryCountHistoryRepository.findByPidAndCtimeAndDtype(pid,
				LocalDate.now().toString(), 1);
		FruitRetryCountHistory retry = fruitRetryCountHistoryRepository.findByPidAndCtimeAndDtype(pid,
				LocalDate.now().toString(), -1);
		FruitRetryCountHistoryResp result = new FruitRetryCountHistoryResp(0,
				LocalDate.now().plusDays(1).toString() + " 00:00:00");
		if (retry == null) {
			retry = new FruitRetryCountHistory(LocalDate.now().toString(), pid, -1, 1, TJKUtils.DateTime());
		} else {
			if (retry_1.getDcount()>retry.getDcount()) {
				retry.setLtime(TJKUtils.DateTime());
				retry.setDcount(retry.getDcount() + 1);
			} else {
				return result;
			}

		}

		FruitRetryCountHistory resultRety = fruitRetryCountHistoryRepository.saveAndFlush(retry);
		if (resultRety != null) {
			int lastCount = retry_1.getDcount() - resultRety.getDcount();
			String lstime = "-";
			if (lastCount <= 0) {
				lastCount = 0;
				lstime = LocalDate.now().plusDays(1).toString() + " 00:00:00";
			}
			result = new FruitRetryCountHistoryResp(lastCount, lstime);
		}
		return result;
	}

	@Override
	public CardInfoResp getCardInfo(int rtype, String pid) {
		List<CardNewHistoryResp> nlist=new ArrayList<CardNewHistoryResp>();
		CatDevUserInfo userInfo = catDevService.getCatDevUserInfoByPid(pid);
		List<CardNewHistory> newHistory=cacheService.getCardNewHistory(pid,userInfo);
		int pokers=cacheService.getCardPokerCount(pid);
		
		if(newHistory!=null&&!newHistory.isEmpty()) {
			newHistory.forEach(newHistorys->{
				nlist.add(new CardNewHistoryResp(newHistorys.getCtime(),newHistorys.getDcount(), newHistorys.getDstatus()));
			});
		}
		CardInfoResp result=codao.selectOne(new CardInfoResp(pid), "getCardInfo");
		if(result!=null) {
			CardDrawCountHistoryResp cards=cacheService.getCardDrawCount(pid);
			if(cards!=null) {
				result.setCards(cards.getDcount());
//				result.setLtime(cards.getLtime());
				String sendCardTime = getSendCardTime(1);
				String lastTime;
				if (sendCardTime.equals("00:00:00")) {
					Calendar calendar=Calendar.getInstance();
					calendar.add(Calendar.DAY_OF_MONTH, 1);
					lastTime=DateAPIUtils.dateToString(calendar.getTime(), "yyyy-MM-dd 00:00:00");
				}else {
					lastTime=TJKUtils.DateTime(TJKUtils.YYYY_MM_DD)+" "+sendCardTime;
				}
				result.setLtime(lastTime);
			}
			/* 人民币和现金豆数 */
			result.setBeans(cacheService.getCatDevLastBeans(pid));
			result.setRmb(cacheService.getCatDevLastRMB(pid));
			result.setNlist(nlist);
			result.setPokers(pokers);
			//设置是否为今日第一次进入,默认非第一次登录
			Integer isFirst = intDao.selectOne(new CardDrawBannerResp(pid,1), "isTodayFirstCome");
			result.setIsFirst(isFirst);
			//获取banner
			List<CardDrawBannerResp> bannerList = getCardBanner(rtype, pid);
			//判断是否展示过弹窗
			result.setIsShow(getPopupStatus(1, pid,0));
			result.setBannerList(bannerList);
		}
		//如果为IOS端，需对图片进行区分
		if (result!=null && rtype==1) {
			result.getBannerList().forEach(banner->{
				banner.setEntryIcon(banner.getEntryIcon().replace(".png", "_ios.png"));
			});
		}
		return result;
	}

	@SuppressWarnings("unchecked")
	@Override
	@Transactional
	public CardDrawHistoryResp getCardDraw(int rtype, String pid,String code,int gtype) {
		//获取用户信息
		CatDevUserInfo devUserInfo = catDevService.getCatDevUserInfoByPid(pid);
		
		Map<String, Object> cardInstance = DrawProportionUtil.getCardInstancePlus(devUserInfo.getUtype());
		//刮刮卡,概率配置
		String[] fieldArray= (String[]) cardInstance.get("fieldArray");
		int[] beanNumArray= (int[]) cardInstance.get("beanNumArray");
		List<Prize> prizeList=JSON.parseArray((String) cardInstance.get("prizeList"), Prize.class);
		/*查询总刮卡次数，若刮卡次数为20的倍数则视为新一轮*/
		prizeList=setCardPrizeList(pid,prizeList,beanNumArray);
		//按比重抽取个数
		String field = CalculateUtil.ratioExtract(prizeList);
		//获取对应的位置
		int index = Arrays.asList(fieldArray).indexOf(field);
		//中奖对象
		CardDrawHistory cardDrawHistory=new CardDrawHistory(pid,TJKUtils.DateTime(),index==4?-1:0,gtype,
				beanNumArray[index],index==4?0:1,TJKUtils.DateTime());
		//保存中奖记录
		if(cardDrawHistoryRepository.saveAndFlush(cardDrawHistory)==null) {
			return null;
		}
		
		String sendCardTime =LocalDate.now().toString()+" "+getSendCardTime(0);
		//如果为1500元的刮刮卡则不需要消耗刮卡次数
		if (gtype!=12) {
			//获取已消耗的抽奖次数
			CardDrawCountHistory cardDrawCountHistory=cardDrawCountHistoryRepository.findByPidAndCtimeAndDtype(pid,
							DateAPIUtils.getNowTimeString(DateAPIUtils.FORMATTER_YYYYMMDD), -1);
			
			//抽奖次数减少一次
			if (cardDrawCountHistory == null) {
				cardDrawCountHistory = new CardDrawCountHistory(DateAPIUtils.getNowTimeString(DateAPIUtils.FORMATTER_YYYYMMDD), pid, -1, 1, sendCardTime);
			} else {
				cardDrawCountHistory.setDcount(cardDrawCountHistory.getDcount() + 1);
				cardDrawCountHistory.setLtime(sendCardTime);
			}
			//保存消耗对象
			cardDrawCountHistoryRepository.saveAndFlush(cardDrawCountHistory);
		}
		
		//banner信息修改
		//查询出对应的记录
		CardDrawEntryInfo drawEntryInfo = cardDrawEntryInfoDao.selectOne(new CardDrawEntryInfo(pid,code), "getCardBannerInfo");
		drawEntryInfo.setGcards(drawEntryInfo.getGcards()+1);
		CardDrawBannerConf bannerConf = cardDrawBannerConfRepository.findById(drawEntryInfo.getCid());
		//算出是否还有刮卡次数
		if (bannerConf.getCards()-drawEntryInfo.getGcards()<1) {
			drawEntryInfo.setStatus(0);
		}
		drawEntryInfo.setLtime(TJKUtils.DateTime());
		cardDrawEntryInfoDao.update(drawEntryInfo);
		
		//封装响应参数
		CardDrawHistoryResp resp=new CardDrawHistoryResp();
		BeanUtils.copyProperties(cardDrawHistory, resp);
		//设置中奖个数
		resp.setZcount(Integer.parseInt(field));

		String nextSendCardTime = getSendCardTime(1);
		if (nextSendCardTime.equals("00:00:00")) {
			nextSendCardTime=LocalDate.now().plusDays(1).toString()+" "+getSendCardTime(1);
		}else {
			nextSendCardTime=LocalDate.now().toString()+" "+getSendCardTime(1);
		}
		resp.setLstime(nextSendCardTime);
		
		/* 存储刮刮卡每日游戏信息 */
		asyncService.insertCardGameInfo(rtype, pid);
		
		return resp;
	}

	/**
	 * 设置刮卡奖品数量
	 * @date 2019-12-10 10:34:55
	 * @param prizeList
	 * @return
	 */
	private List<Prize> setCardPrizeList(String pid,List<Prize> prizeList,int[] beanNumArray) {
		//查询今日刮卡数量
		CardDrawCountHistory countHistory = cardDrawCountHistoryRepository.findByPidAndCtimeAndDtype(pid, LocalDate.now().toString(), -1);
		int count=countHistory==null?0:countHistory.getDcount();
		//如果今日没有刮卡则为初始值或者已经挂完20个卡片，可开启下一轮
		if (count==0 || count%20==0) {
			return prizeList;
		}
		//查询抽奖情况
		List<CardInfoResp> list = codao.list(new CardInfoResp(pid,count%20), "getLast20CardResult");
		List<String> indexList = new ArrayList<>(beanNumArray.length);
		for (int s : beanNumArray) {
			indexList.add(s+"");
		}
		//计算奖品数量
		list.forEach(resp->{
			int index = indexList.indexOf(resp.getBeans()+"");
			if (index>-1) {
				prizeList.get(index).setPrizeCount(prizeList.get(index).getPrizeCount()-resp.getGcards());
			}
		});
		return prizeList;
	}

	/**
	 * 获取下一次发卡时间
	 * @param type 0.上次发卡时间、1.下次发卡时间
	 * @return
	 */
	private String getSendCardTime(int type) {
		//配置发卡时间
		String[] timeArray= {"00:00:00","08:00:00","12:00:00","17:00:00","20:00:00"};
		
		//设置下次发卡时间
		Calendar calendar=Calendar.getInstance();
		int hour = calendar.get(Calendar.HOUR_OF_DAY);
		
		//遍历查找下次发卡时间
		for (int i = 0; i < timeArray.length; i++) {
			if (i!=timeArray.length-1) {
				int time1 = Integer.parseInt(timeArray[i].substring(0, 2));
				int time2 = Integer.parseInt(timeArray[i+1].substring(0, 2));
				if (hour>=time1 && hour<time2) {
					return type==0?timeArray[i]:timeArray[i+1];
				}
			}else {
				return type==0?timeArray[i]:timeArray[0];
			}
		}
		return null;
	}

	@Override
	public CardDrawHistoryResp getCardDrawDouble(int rtype, CardDrawHistory drawHistory) {
		//如果不翻倍
		if (drawHistory.getFtype()==-1) {
			drawHistory.setDstatus(1);
			drawHistory.setLtime(TJKUtils.DateTime());
			if(cardDrawHistoryRepository.saveAndFlush(drawHistory)==null) {
				log.error("getTurnDrawDouble:pid="+drawHistory.getPid()+"领取失败");
				return null;
			}
		}else {
			//设置为已翻倍
			drawHistory.setFtype(1);
			drawHistory.setLtime(TJKUtils.DateTime());
			drawHistory.setDcount(drawHistory.getDcount()*2);	
			if(cardDrawHistoryRepository.saveAndFlush(drawHistory)==null) {
				log.error("getTurnDrawDouble:pid="+drawHistory.getPid()+"翻倍失败");
				return null;
			}
		}
		//异步更新抽奖结果
		asyncService.insertCardGameInfo(rtype, drawHistory.getPid());
		
		CardDrawHistoryResp resp=new CardDrawHistoryResp();
		BeanUtils.copyProperties(drawHistory, resp);
		//获取下次下发卡时间
		resp.setLstime(LocalDate.now().toString()+" "+getSendCardTime(1));
		return resp;
	}

	@Override
	@Transactional
	public CardPokerDrawHistoryResp getCardPokerDraw(int rtype, String pid) {
		CardPokerDrawHistoryResp result=null;
		CardPokerDrawHistory resultEntity= randCardPoker(pid);
		log.info("-randPoker-->"+JSON.toJSONString(resultEntity));
		if(resultEntity!=null&&cardPokerDrawHistoryRepository.saveAndFlush(resultEntity)!=null) {
			
			CardPokerDrawCountHistory DrawCount=cardPokerDrawCountHistoryRepository.findByPidAndCtimeAndDtype(pid, LocalDate.now().toString(), -1);
			if(DrawCount==null) {
				DrawCount=new CardPokerDrawCountHistory(LocalDate.now().toString(), pid, -1, 1, TJKUtils.DateTime());
			}else {
				DrawCount.setDcount(DrawCount.getDcount()+1);
				DrawCount.setLtime(TJKUtils.DateTime());
			}
			if(cardPokerDrawCountHistoryRepository.saveAndFlush(DrawCount)!=null) {
				int lastCount=cacheService.getCardPokerCount(pid);
				result=new CardPokerDrawHistoryResp(resultEntity.getFid(), resultEntity.getFtype(), resultEntity.getGtype(), resultEntity.getDcount(), lastCount);
			}
		}
		return result;
	}
	
	/**
	 * 
	 * @info 获取刮刮卡-翻牌游戏金豆数
	 * @author Link
	 * @date 2019-11-20 16:20
	 * @param pid
	 * @return
	 */
	private CardPokerDrawHistory randCardPoker(String pid) {
		CardPokerDrawHistory result=new CardPokerDrawHistory(pid, LocalDate.now().toString(), 0, 0, 1, TJKUtils.DateTime());
		/* 产生随机数：中奖类型(1.金、2.银、3.铜)*/
		int randGtype = RandomUtils.nextInt(1, 4);
		result.setGtype(randGtype);
		/* 金卡60--99随机；银卡30--59随机；铜卡10--29随机 */
		int start=10,end=42;
		if(randGtype==1) {
			start=60;
			end=100;
		}else if(randGtype==2) {
			start=30;
			end=60;
		}
		/* 产生随机数：现金豆数量*/
		int dcount = RandomUtils.nextInt(start,end);
		result.setDcount(dcount);
		return result;
	}

	@Override
	public CardPokerDrawHistoryResp getCardPokerDrawDouble(int rtype, CardPokerDrawHistory poker) {
		CardPokerDrawHistoryResp result=null;
		poker.setFtype(1);
		poker.setDcount(poker.getDcount()*3);
		poker.setLtime(TJKUtils.DateTime());
		if(cardPokerDrawHistoryRepository.saveAndFlush(poker)!=null) {
			int lastCount=cacheService.getCardPokerCount(poker.getPid());
			result=new CardPokerDrawHistoryResp(poker.getFid(),poker.getFtype(), poker.getGtype(), poker.getDcount(), lastCount);
		}
		return result;
	}

	@Override
	@Transactional
	public List<CardDrawBannerResp> getCardBanner(Integer rtype, String pid) {
		//查询今日刮卡抽奖banner数据
		List<CardDrawBannerResp> list = cardDrawBannerRespDao.list(new CardDrawBannerResp(pid,1), "getCardBannerList");
		List<CardDrawEntryInfo> infoList;
		if (list==null || list.size()<1) {
			//查询今日是否已经发卡
			CardDrawBannerResp bannerResp = cardDrawBannerRespDao.selectOne(new CardDrawBannerResp(pid), "getTodayCardBannerNum");
			if (bannerResp.getCards()>0) {
				return list;
			}
			list = initCardDrawEntryInfoList(pid);
			infoList = JSON.parseArray(JSON.toJSONString(list), CardDrawEntryInfo.class);
			//更新
			cardDrawEntryInfoDao.delete(new CardDrawEntryInfo(pid));
			//插入
			if (cardDrawEntryInfoDao.insertBatch(infoList, "insertBatch")==false) {
				log.error("getCardBanner:pid="+pid+"刮刮卡banner数据初始化失败！");
				return null;
			}
		}else if(!list.get(0).getCtime().equals(TJKUtils.DateTime("yyyy-MM-dd"))){
			list = initCardDrawEntryInfoList(pid);
			infoList = JSON.parseArray(JSON.toJSONString(list), CardDrawEntryInfo.class);
			//更新
			if (cardDrawEntryInfoDao.delete(new CardDrawEntryInfo(pid))==false) {
				log.error("getCardBanner:pid="+pid+"刮刮卡banner数据更新失败！");
				return null;
			}
			//插入
			if (cardDrawEntryInfoDao.insertBatch(infoList, "insertBatch")==false) {
				log.error("getCardBanner:pid="+pid+"刮刮卡banner数据初始化失败！");
				return null;
			}
		}
		return list;
	}
	
	/**
	 * 初始化刮刮卡banner条目
	 */
	private List<CardDrawBannerResp> initCardDrawEntryInfoList(String pid) {
		//初始化集合
		List<CardDrawBannerResp> respList=new ArrayList<>();
		//获取初始化配置
		List<CardDrawBannerConf> list = cardDrawBannerConfRepository.findByStatus(1);
		int code;
		//打乱顺序
		Collections.shuffle(list);
		String createDate = TJKUtils.DateTime(TJKUtils.YYYY_MM_DD);
		String updateDate = TJKUtils.DateTime();
		String temp;
		int index=0;
		for (CardDrawBannerConf cardDrawEntryConf:list) {
			code=cardDrawEntryConf.getId();
			if (cardDrawEntryConf.getSort()==0) {
				cardDrawEntryConf.setSort(index);
				index++;
			}
			temp="10"+(code>9?code:"0"+code);
			respList.add(new CardDrawBannerResp(pid,temp,cardDrawEntryConf,createDate,updateDate));
		}
		//排序
		Collections.sort(respList,new Comparator<CardDrawBannerResp>() {
			@Override
			public int compare(CardDrawBannerResp o1, CardDrawBannerResp o2) {
				return o2.getSort()-o1.getSort();
			}
			
		});
		return respList;
	}

	@Override
	public BoxInfoResp getBoxInfo(Integer rtype, String pid) {
		//获取当前钥匙数量,及各游戏领取进度
		BoxInfoResp boxInfoResp = boxInfoRespDao.selectOne(new BoxInfoResp(pid), "getBoxInfo");
		//特殊处理,暂未开通水果机与大转盘游戏时,默认送两个钥匙
//		if (boxInfoResp.getDcount()==0 && boxInfoResp.getCvsStatus()==0 && boxInfoResp.getCardStatus()==0) {
//			String ctime=LocalDate.now().toString();
//			String ltime=TJKUtils.DateTime();
//			boxDrawCountHistoryRepository.save(new BoxDrawCountHistory(ctime, pid, 0, 1, ltime));
//			boxDrawCountHistoryRepository.flush();
//			boxInfoResp.setDcount(1);
//			boxInfoResp.setTurnStatus(1);
//			boxInfoResp.setFruitStatus(1);
//		}
		/*用户现金豆总数*/
		long beans = cacheService.getCatDevLastBeans(pid);
		boxInfoResp.setBeans(beans);
		return boxInfoResp;
	}

	@Override
	public Boolean addBoxKey(Integer rtype, String pid, Integer type) {
		BoxDrawCountHistory history=new BoxDrawCountHistory(pid); 
		history.setDtype(type);
		history.setCtime(TJKUtils.DateTime(TJKUtils.YYYY_MM_DD));
		history.setDcount(1);
		history.setLtime(TJKUtils.DateTime());
		return boxDrawCountHistoryRepository.saveAndFlush(history)==null?false:true;
	}

	@Override
	@Transactional
	public BoxInfoResp getBoxCardDraw(Integer rtype, String pid) {
		//开宝箱获取宝箱奖品信息
		BoxDrawHistory boxDrawHistory=new BoxDrawHistory(pid);
		
		//抽取开宝箱获取的现金豆数量
		String[] fieldArray= {"66","77","88","99"};
		double[] proportions= {25,25,25,25};
		String extract = CalculateUtil.ratioExtract(fieldArray, proportions);
		int beanNum = Integer.parseInt(extract);
		boxDrawHistory.setDcount(beanNum);
		boxDrawHistory.setCtime(TJKUtils.DateTime());
		boxDrawHistory.setLtime(TJKUtils.DateTime());
		boxDrawHistory.setDstatus(1);
		
		//保存中奖信息
		if (boxDrawHistoryRepository.saveAndFlush(boxDrawHistory)==null) {
			log.error("getBoxCardDraw:保存中奖信息失败pid="+pid);
			return null;
		}
		
		//开宝箱
		BoxDrawCountHistory history= boxDrawCountHistoryRepository.findByPidAndDtypeAndCtime(pid, -1,
				TJKUtils.DateTime(TJKUtils.YYYY_MM_DD));
		
		if (history==null) {
			history=new BoxDrawCountHistory(TJKUtils.DateTime(TJKUtils.YYYY_MM_DD), pid,
					-1, 4, TJKUtils.DateTime());
		}else {
			history.setDcount(history.getDcount()+4);
			history.setLtime(TJKUtils.DateTime());
		}
		
		if (boxDrawCountHistoryRepository.saveAndFlush(history)==null) {
			log.error("getBoxCardDraw:保存信息失败pid="+pid);
			return null;
		}
		
		//获取当前钥匙数量,及各游戏领取进度
		BoxInfoResp boxInfoResp = boxInfoRespDao.selectOne(new BoxInfoResp(pid), "getBoxInfo");
		boxInfoResp.setBoxBeanNum(beanNum);
		/*用户现金豆总数*/
		long beans = cacheService.getCatDevLastBeans(pid)+beanNum;
		boxInfoResp.setBeans(beans);
		return boxInfoResp;
	}

	@Override
	public List<ScrollBarInfoResp> getCardScrollBarList(Integer rtype) {
		List<ScrollBarInfoResp> list = cacheService.getCardScrollBarList();
		Collections.shuffle(list);
		return list;
	}

	@Override
	public List<String> getFruitScrollBarList(Integer rtype) {
		//获取所有的姓氏
		List<String> surnameList=cacheService.getScrollBarInfoData(1, 2);
		//将姓氏展开
		List<String> surnameArray=new ArrayList<>();
		for (String surnameString : surnameList) {
			surnameArray.addAll(Arrays.asList(surnameString.split(",")));
		}
		
		//获取所有名
		List<String> nameList = cacheService.getScrollBarInfoData(1, 3);
		//将名展开
		List<String> nameArray=new ArrayList<>();
		for (String nameString : nameList) {
			nameArray.addAll(Arrays.asList(nameString.split(",")));
		}
		
		//组成100随机姓名
		List<String> resultList=new ArrayList<>();
		//配置奖品
		String[] prizeName= {"腾讯会员1月","小米无线蓝牙耳机","小米MI手环4"};
		double[] proportions= {60,20,20};
		//获奖时间
		String[] fieldArray= {"1","2","3","4","5","6","7","8","9","10"};
		double[] timeProportions= {30,20,10,5,10,5,5,5,5,5};
		StringBuilder builder=new StringBuilder();
		Random random=new Random();
		for (int i = 0; i < 100; i++) {
			//随机拼接名称
			builder.append(surnameArray.get(random.nextInt(surnameArray.size()))
					+nameArray.get(random.nextInt(nameArray.size())));
			builder.append("* "+(random.nextInt(10)+1)+"分钟前获得");
			builder.append(CalculateUtil.ratioExtract(prizeName, proportions));
			resultList.add(builder.toString());
			//清空
			builder.setLength(0);
		}
		return resultList;
	}

	@Override
	public CVSPrizeInfoResp getCVSPrizeInfoResp(String pid) {
		CVSPrizeInfoResp infoResp = cvsPrizeInfoRespDao.selectOne(new CVSDrawHistory(pid), "getCVSMaxInfo");
		//如果没有记录
		if (infoResp==null) {
			infoResp=new CVSPrizeInfoResp();
			infoResp.setStype(RandomUtils.nextInt(0, 6));
		}
		String[] nameArray= {"小米扫地机器人","iPhone 11","小米平衡车","优酷会员卡","九阳榨汁机","9999现金豆红包"};
		String imgUrl= "https://img.jiuqumao.cn/imgs/cvs/prize_";
		infoResp.setIcon(imgUrl+infoResp.getStype()+".png");
		infoResp.setTotal(50);
		infoResp.setName(nameArray[(int) infoResp.getStype()]);
		
		//查询今日礼包是否领取
		CVSDrawHistory dailySuprise = cacheService.getCVSDailySuprise(LocalDate.now().toString(), pid);
		infoResp.setIsReceive(dailySuprise==null || dailySuprise.getDcount()<1?0:1);
		return infoResp;
	}

	@Override
	public Boolean getCVSStartReward(Integer rtype, List<CVSDrawHistory> list) {
		list.forEach(obj->{
			obj.setDstatus(1);
			obj.setLtime(TJKUtils.DateTime());
		});
		if(cvsDrawHistoryRepository.saveAll(list)!=null) {
			cvsDrawHistoryRepository.flush();
			return true;
		}
		return false;
	}

	@Override
	public Boolean updatePopupStatus(Integer rtype, String pid, int pindex) {
		//标记更新弹窗
		getPopupStatus(pindex, pid, 1);
		return true;
	}

}
